<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Promotion\Ctl;

use Srv\Apps\Apis\Common\DefCtl\DefChannelCtl;
use Srv\Apps\Apis\Common\IdxCtl\IdxIp;
use Srv\Apps\Apis\User\Ctl\UserCtl;
use Srv\Apps\Proto\DTO\Promotion\TgEventListDTO;
use Srv\Apps\Proto\Enum\TgEventHandleTypeEnum;
use Srv\Apps\Proto\Enum\TgEventTypeEnum;
use Srv\Apps\Proto\VO\Promotion\TgEventListVO;
use Srv\Apps\Proto\VO\Promotion\TgEventVO;
use Srv\Apps\Proto\VO\User\UserInfoBasicVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;
use Srv\Libs\Tools\IpAddr;

final class TgEventCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write



    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return TgEventListVO|null
     * getTgEventList
     */
    public function getTgEventList(Page $Page, array $whereData): ?TgEventListVO
    {
        $limitString            = $Page->getLimitString();
        $whereString            = ' WHERE tger_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case TgEventListDTO::_tgerId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'tger_id='. intval($val);
                    break;
                case TgEventListDTO::_userId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'user_id='. intval($val);
                    break;
                case TgEventListDTO::_dupId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'dup_id='. intval($val);
                    break;
                case TgEventListDTO::_eventType:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'tger_event_type='. intval($val);
                    break;
                case TgEventListDTO::_handle:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'tger_handle='. intval($val);
                    break;
                case TgEventListDTO::_idNum:
                    if(strlen($val) > 10 && is_numeric($val)){
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'user_id='. intval($val);
                    }else{
                        $tempSql        = 'SELECT user_id FROM '.$this->DbAuto->getTableNameAll('user_info').' WHERE usi_delete=0 AND usi_idnum LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'user_id IN('. $tempSql .')';
                    }
                    break;
                case TgEventListDTO::_channel:
                    $dchtId             = DefChannelCtl::tag()->getIdByKey($val);
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'dcht_id='.$dchtId;
                    break;
                case TgEventListDTO::_createTimeStart:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'tger_create_time>='.intval($val);
                    break;
                case TgEventListDTO::_createTimeStop:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'tger_create_time<='.intval($val);
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS tger_id, dup_id, dcht_id, user_id, tger_event_ip, tger_event_type, tger_event_data, tger_handle, tger_handle_time, tger_create_time, tger_update_time FROM '.$this->DbAuto->getTableNameAll('tg_event_record').$whereString.' ORDER BY tger_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $TgEventVOList          = [];
        if(CommArray::isForeach($list)){
            $userIdList                 = array_map('intval', array_unique(array_column($list, 'user_id')));
            $UserInfoBasicVOList        = UserCtl::tag()->getUserInfoBasicBatch($userIdList);
            foreach($list as $info){
                $tgerIdItem             = intval($info['tger_id']??0);
                if($tgerIdItem < 1) continue;
                $TgEventVO              = $this->getTgEventVO($info);
                if(!($TgEventVO instanceof TgEventVO)) continue;
                $UserInfoBasicVO        = $UserInfoBasicVOList[intval($info['user_id'])]??null;
                if($UserInfoBasicVO instanceof UserInfoBasicVO)$TgEventVO->setUserInfoBasic($UserInfoBasicVOList[intval($info['user_id'])]);
                $TgEventVOList[]        = $TgEventVO;
            }
        }
        $TgEventListVO          = new TgEventListVO();
        $TgEventListVO->setList($TgEventVOList);
        $TgEventListVO->setPage($Page->getPageVO($totalNum));
        return $TgEventListVO;
    }

    /**
     * @param array $info
     * @return TgEventVO|null
     * getTgEventVO
     */
    public function getTgEventVO(array $info):?TgEventVO
    {
        $tgerId             = intval($info['tger_id']??0);
        if($tgerId < 1) return null;
        $TgEventVO          = new TgEventVO();
        $TgEventVO->setTgerId($tgerId);
        $TgEventVO->setDupId(intval($info['dup_id']));
        $TgEventVO->setChannel(DefChannelCtl::tag()->getExtStrById(intval($info['dcht_id']), DefChannelCtl::EXT_NAME));
        $TgEventVO->setUserId(intval($info['user_id']));
        $eventIpStr         = IdxIp::tag()->getIpStrByIntStr($info['tger_event_ip']);
        $eventIpArea        = IpAddr::getLocationInfo($eventIpStr);
        $TgEventVO->setEventIpStr($eventIpStr.'('.($eventIpArea['country']??'').')');
        $TgEventVO->setEventData(trim($info['tger_event_data']));
        $TgEventVO->setEventType(TgEventTypeEnum::parseValue($info['tger_event_type']));
        $TgEventVO->setHandle(TgEventHandleTypeEnum::parseValue($info['tger_handle']));
        $TgEventVO->setHandleTime(intval($info['tger_handle_time']));
        $TgEventVO->setCreateTime(intval($info['tger_create_time']));
        $TgEventVO->setUpdateTime(intval($info['tger_update_time']));
        return $TgEventVO;
    }
}